package com.junmeng.lib.cascade
import com.junmeng.lib.cascade.bean.Config
import com.junmeng.lib.cascade.util.IdeaGitVcsFileUtil
import com.junmeng.lib.cascade.util.Log
import com.junmeng.lib.cascade.util.SourceCascadeUtil
import org.gradle.api.Plugin
import org.gradle.api.initialization.Settings
import org.yaml.snakeyaml.Yaml
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream

class SourceCascadePlugin : Plugin<Settings> {
    companion object {
        const val LOCAL_CONFIG_FILENAME = "sourceCascadeLocalConfig.yml"
        const val CONFIG_ENABLE_CASCADE = "enableCascade"
        const val CONFIG_ENABLE_GIT = "enableGit"
        const val CONFIG_AUTO_ADD_TO_GITIGNORE = "autoAddToGitignore"
        const val CONFIG_CASCADE_MODULE_MAP = "cascadeModuleMap"
        const val DOT_GITIGNORE = ".gitignore"

        val LOCAL_CONFIG_FILE_TEMPLATE_PATH = "template/${LOCAL_CONFIG_FILENAME}"
//        val LOCAL_CONFIG_FILE_TEMPLATE_PATH = "template${File.separator}${LOCAL_CONFIG_FILENAME}"
    }

    override fun apply(settings: Settings) {
        Log.log("rootProject.name=${settings.rootProject.name}")
        Log.log("rootDir=${settings.rootDir}")
        var file = File(settings.rootDir, LOCAL_CONFIG_FILENAME)
        if (!file.exists()) {
            val contextClassLoader = Thread.currentThread().contextClassLoader
            val ins: InputStream? =
                contextClassLoader.getResourceAsStream(LOCAL_CONFIG_FILE_TEMPLATE_PATH)//使用File.separator此处会导致返回null
            ins?.let {
                val fos = FileOutputStream(file)
                with(fos) {
                    this.write(ins.readBytes())
                }
                Log.log("模板配置文件已拷贝到此目录：${file.absolutePath}")
            } ?: kotlin.run {
                Log.log("找不到模板配置文件:${LOCAL_CONFIG_FILENAME}，需要用户在项目根目录下自己手动创建")
            }
        }

        Log.log("组件级联本地配置文件(${file.absolutePath})是否存在：${file.exists()}")

        if (!file.exists()) {
            Log.log("未找到组件级联本地配置文件(${LOCAL_CONFIG_FILENAME}),组件级联功能无法启用")
            return
        }
        val config = getConfigFromYmlFile(file)
        if (config == null) {
            Log.log("解析${LOCAL_CONFIG_FILENAME}文件失败，请检查是否符合yml格式")
            return
        }
        Log.log("级联配置开始")
        handleConfig(settings, config)
        Log.log("级联配置结束")
    }

    private fun getConfigFromYmlFile(ymlFile: File): Config? {
        val fileInputStream = FileInputStream(ymlFile)
        with(fileInputStream) {
            val map: Map<String, Any>? = Yaml().load(fileInputStream)
            Log.log("${LOCAL_CONFIG_FILENAME}文件内容：${map}")
            map?.let {
                // 获取配置项
                val enableCascade: Boolean =
                    (it[CONFIG_ENABLE_CASCADE] as Boolean?)
                        ?: false
                val enableGit: Boolean =
                    (it[CONFIG_ENABLE_GIT] as Boolean?)
                        ?: false
                val autoAddToGitignore: Boolean = (it[CONFIG_AUTO_ADD_TO_GITIGNORE] as Boolean?)
                    ?: false
                val cascadeModuleMap: Map<String, String>? =
                    it[CONFIG_CASCADE_MODULE_MAP] as Map<String, String>?
                return Config(
                    enableCascade,
                    enableGit,
                    autoAddToGitignore,
                    cascadeModuleMap ?: mapOf()
                )
            } ?: kotlin.run {
                return null
            }
        }
    }

    private fun handleConfig(settings: Settings, config: Config) {
        SourceCascadeUtil.startCascade(settings, config)
        IdeaGitVcsFileUtil.handleGit(settings, config)
        handleGitignore(settings, config)
    }

    private fun handleGitignore(settings: Settings, config: Config) {
        if (config.autoAddToGitignore) {
            val targetContent = "/${LOCAL_CONFIG_FILENAME}"
            var file = File(settings.rootDir, DOT_GITIGNORE)
            if (file.exists()) {
                val lines = file.readLines()
                val hasContent = lines.contains(targetContent)
                Log.log("${DOT_GITIGNORE}文件中是否已经存在行内容(${targetContent}):${hasContent}")
                if (!hasContent) {
                    file.appendText("${targetContent}\n")
                    Log.log("内容(${targetContent})已追加到文件(${DOT_GITIGNORE})末尾")
                }
            }
        }
    }

}